package com.jspgou.cms;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.SAXReader;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.jspgou.common.util.Num62;
import com.jspgou.common.web.RequestUtils;

/* *
 *类名：WebChatSubmit
 *功能：微信支付各接口请求提交类
 *详细：
 */
public class WeChat {
	//private static String Key = "192006250b4c09247ec02edce69f6a2d";  
	
	//支付appid   
	public static final String APPID="wxc596191fde33119f";
	//商户号
	public static final String MCHId="1264316901";
	//商户密钥
	public static final String KEY="3jeecmszjc0791DzdJovJeecmsJeebbs";
	private static final int BLACK = 0xFF000000;//黑色
    private static final int WHITE = 0xFFFFFFFF;//白色
    public static final String characterEncoding = "UTF-8";
    /**
     * 微信统一下单接口
     */
    public static final String UNIFORM_SINGLE_INTERFACE="https://api.mch.weixin.qq.com/pay/unifiedorder";
    /**
     * 微信支付页面
     */
    public static final String WECHATPAYMENT="tpl.weChatPayment";
	
	/**
	 * 日期格式化对象，将当前日期格式转化为ddHHmmss格式，用于生成随机数
	 */
	public static final DateFormat nameDf =new SimpleDateFormat("ddHHmmss");
	
	/**
	 * 微信支付生成随机数，长度不超36位
	 */
	public static String getWCRandomNumber(Integer num){
		return nameDf.format(new Date())+RandomStringUtils.random(num,Num62.N62_CHARS);
	}
	
	/**
	 * 微信支付签名sign
	 * @param characterEncoding
	 * @param param
	 * @param key
	 * @return
	 */
	
	
	/**
	 * 微信支付签名sign
	 * @param characterEncoding
	 * @param param
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String createSign(Map<String, String> param,String key){
		//签名步骤一：按字典排序参数
		List list=new ArrayList(param.keySet());
		Object[] ary =list.toArray();
		Arrays.sort(ary);
		list=Arrays.asList(ary);
		String str="";
		for(int i=0;i<list.size();i++){
			str+=list.get(i)+"="+param.get(list.get(i)+"")+"&";
		}
		//签名步骤二：加上key
		str+="key="+key;
		//步骤三：加密并大写
		str=MD5Encode(str,characterEncoding).toUpperCase();
		return str;
	}
	
	public static String MD5Encode(String origin,String charsetName){
		String resultString=null;
		try{
			resultString=new String(origin);
			MessageDigest md=MessageDigest.getInstance("MD5");
			if(charsetName==null||"".equals(charsetName)){
				resultString=byteArrayToHexString(md.digest(resultString.getBytes()));
			}else{
				resultString=byteArrayToHexString(md.digest(resultString.getBytes(charsetName)));
			}
		}catch(Exception e){
			
		}
		return resultString;
	}
	
	private static String byteArrayToHexString(byte b[]){
		StringBuffer resultSb=new StringBuffer();
		for(int i=0;i<b.length;i++){
			resultSb.append(byteToHexString(b[i]));
		}
		return resultSb.toString();
	}
	
	private static String byteToHexString(byte b){
		int n=b;
		if(n<0){
			n+=256;
		}
		int d1=n/16;
		int d2=n%16;
		return hexDigits[d1]+hexDigits[d2];
	}
	
	private static final String hexDigits[]={ "0", "1", "2", "3", "4", "5",  
        "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    /**
     * 利用微信“统一下单”接口获取返回的数据 
     * @param urlStr
     * @param xmlInfo
     * @return
     */
    public static String testPost(String urlStr,String xmlInfo) {
    	String line1 = "";  
    	try {  
            URL url = new URL(urlStr);  
            URLConnection con = url.openConnection();  
            con.setDoOutput(true);  
            con.setRequestProperty("Pragma:", "no-cache");  
            con.setRequestProperty("Cache-Control", "no-cache");  
            con.setRequestProperty("Content-Type", "text/xml");  
  
            OutputStreamWriter out = new OutputStreamWriter(con  
                    .getOutputStream());           
            out.write(new String(xmlInfo.getBytes(characterEncoding)));  
            out.flush();  
            out.close();  
            BufferedReader br = new BufferedReader(new InputStreamReader(con  
                    .getInputStream()));  
            String line = "";  
            for (line = br.readLine(); line != null; line = br.readLine()) {  
                line1+=line;  
            } 
            line1 = new String((line1).getBytes("GBK"),characterEncoding);
            return line1;
        } catch (MalformedURLException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }
		return null;  
    }  
    
    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点，则此节点的值是子节点的xml数据。
     * @param strxml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
    	strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\""+characterEncoding+"\"");   	 
    	if(null == strxml || "".equals(strxml)) {
    		return null;
    	}
    	Map m = new HashMap();
    	InputStream in = new ByteArrayInputStream(strxml.getBytes(characterEncoding));
    	SAXBuilder builder = new SAXBuilder();
    	Document doc = builder.build(in);
    	Element root = doc.getRootElement();
    	List list = root.getChildren();
    	Iterator it = list.iterator();
    	while(it.hasNext()) {
    		Element e = (Element) it.next();
    		String k = e.getName();
    		String v = "";
    		List children = e.getChildren();
    		if(children.isEmpty()) {
    			v = e.getTextNormalize();
    		} else {
    			v =getChildrenText(children);
    		}
    		m.put(k, v);
    	}
    	//关闭流
    	in.close();
    	return m;
    }
    
    /**
     * 获取子结点的xml
     * @param children
     * @return String
     */
    public static String getChildrenText(List children) {
    	StringBuffer sb = new StringBuffer();
    	if(!children.isEmpty()) {
    		Iterator it = children.iterator();
    		while(it.hasNext()) {
    			Element e = (Element) it.next();
    			String name = e.getName();
    			String value = e.getTextNormalize();
    			List list = e.getChildren();
    			sb.append("<" + name + ">");
    			if(!list.isEmpty()) {
    				sb.append(getChildrenText(list));
    			}
    			sb.append(value);
    			sb.append("</" + name + ">");
    		}
    	}
    	return sb.toString();
    }
    
    /**
     * 将需要传递给微信的参数转成xml格式
     * @param parameters
     * @return
     */
    public static String getRequestXml(Map<String,String> parameters){
    	StringBuffer sb = new StringBuffer();
    	sb.append("<xml>");
    	Set es = parameters.entrySet();
    	Iterator it = es.iterator();
    	while(it.hasNext()) {
    		Map.Entry entry = (Map.Entry)it.next();
    		String k=(String)entry.getKey();
    		String v=(String) entry.getValue();
    		if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {
    			sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");
    		}else {
    			sb.append("<"+k+">"+v+"</"+k+">");
    		}
    	}
    		sb.append("</xml>");
    		return sb.toString();
    }
    
    public static void noticeWeChatSuccess(){
    	Map<String,String> parames=new HashMap<String,String>();
    	parames.put("return_code", "SUCCESS");
    	parames.put("return_msg", "OK");
    	//将参数转成xml格式
    	String xmlWeChat = getRequestXml(parames);
    	System.out.println("fasongweixinchenggongshuju==="+xmlWeChat);
    	try{    		
    		testPost(UNIFORM_SINGLE_INTERFACE,xmlWeChat);
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    }
    
    /**  
     * 元转换为分.  
     *   
     * @param yuan  
     *            元  
     * @return 分  
     */  
    public static String fromYuanToFen(Double yuan1) {
    	String yuan=yuan1.toString();
        String fen = "";  
        Pattern pattern = Pattern.compile("^[0-9]+(.[0-9]{2})?{1}");  
        Matcher matcher = pattern.matcher(yuan);  
        if (matcher.matches()) {  
            try {  
                NumberFormat format = NumberFormat.getInstance();  
                Number number = format.parse(yuan);  
                double temp = number.doubleValue() * 100.0;  
                // 默认情况下GroupingUsed属性为true 不设置为false时,输出结果为2,012  
                format.setGroupingUsed(false);  
                // 设置返回数的小数部分所允许的最大位数  
                format.setMaximumFractionDigits(0);  
                fen = format.format(temp);  
            } catch (ParseException e) {  
                e.printStackTrace();  
            }  
        }else{  
            System.out.println("参数格式不正确!");  
        }  
        return fen;  
    }  
    
    public static void main(String[]args){
    	System.out.println(fromYuanToFen(10.01));
    }
    
    /**
	   * 生成二维码图片并直接以流的形式输出到页面
	   * @param code_url
	   * @param response
	   */
	  @RequestMapping("qr_code1.img")
	  @ResponseBody
	  public static void getQRCode1(String code_url,HttpServletResponse response){
	     encodeQrcode(code_url, response);
	  }
	  
	  /**
	   * 生成二维码图片 不存储 直接以流的形式输出到页面
	   * @param content
	   * @param response
	   */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void encodeQrcode(String content,HttpServletResponse response){
		   if(StringUtils.isBlank(content)){        	   
			   return;
		   }
		   MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
		   Map hints = new HashMap();
        hints.put(EncodeHintType.CHARACTER_SET, characterEncoding); //设置字符集编码类型
        BitMatrix bitMatrix = null;
        try {
           bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300, 300,hints);
            BufferedImage image = toBufferedImage(bitMatrix);
            //输出二维码图片流
            try {
                ImageIO.write(image, "png", response.getOutputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
       } catch (WriterException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }         
    }
    
    public static BufferedImage toBufferedImage(BitMatrix matrix) {
	      int width = matrix.getWidth();
	      int height = matrix.getHeight();  
	      BufferedImage image = new BufferedImage(width, height,
	      BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); 
            }
        }  
	          return image;	  
	}
    
    /**
     * 判断是否来自微信, 5.0 之后的支持微信支付
     *
     * @param request
     * @return
     */
    public static boolean isWeiXin(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        if (StringUtils.isNotBlank(userAgent)) {
            Pattern p = Pattern.compile("MicroMessenger/(\\d+).+");
            Matcher m = p.matcher(userAgent);
            String version = null;
            if (m.find()) {
                version = m.group(1);
            }
            return (null != version && NumberUtils.toInt(version) >= 5);
        }
        return false;
    }
    
    /**
     * 处理xml请求信息
     * @param reequest
     * @return
     */
    public static String getXmlRequest(HttpServletRequest request){
    	BufferedReader bis=null;
    	String result="";
    	try{
    		bis=new BufferedReader(new InputStreamReader(request.getInputStream()));
    		String line=null;
    		while((line=bis.readLine())!=null){
    			result+=line;
    		}
    	}catch(Exception e){
    		e.printStackTrace();
    	}finally{
    		if(bis!=null){
    			try{
    				bis.close();
    			}catch(IOException e){
    				e.printStackTrace();
    			}
    		}
    	}
    	return result;
    }

}
